﻿namespace DataIntegration.Extracters
{
    using System.Reflection;
    using Entities;
    using Entities.Triggers;
    using log4net;
    using Messaging.Consumer;
    using Messaging.Publisher;
    using Storage;
    using Utils;
    using Utils.Serialization;

    public abstract class TriggeredExtracter : Extracter
    {
        private static readonly ILog Logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

        private readonly IConsumerFactory consumerFactory;

        private IConsumer consumer;

        private readonly string triggerTopic;

        protected TriggeredExtracter(
                string name, 
                IPublisherFactory publisherFactory, 
                IDataStoreFactory dataStoreFactory,
                string filter,
                IConsumerFactory consumerFactory, 
                string triggerTopic)
            : base(name, publisherFactory, dataStoreFactory, filter)
        {
            Logger.DebugFormat(
                "Creating TriggeredExtracter with name=[{0}] filter[{1}] triggerTopic=[{2}]", 
                name,
                filter,
                triggerTopic);
            this.consumerFactory = consumerFactory;
            this.triggerTopic = triggerTopic;
        }

        public override void Dispose()
        {
            base.Dispose();
            Logger.DebugFormat("Disposing [{0}]", this.name);
            this.Dispose(this.consumer);
        }

        protected override void Setup()
        {
            base.Setup();
            Logger.DebugFormat("Setting up [{0}]", this.name);
            string topic = string.Format("{0}.{1}.{2}", App.Name, MessageType.Trigger, this.triggerTopic);
            this.consumer = this.consumerFactory.GetConsumer(this.DaemonName, MessageType.Trigger, this.name);
            this.consumer.MessageReceived += this.MessageReceived;
            this.consumer.Start();
            this.consumer.ConsumeDurable(topic);
        }

        protected void MessageReceived(string messageId, string message)
        {
            Logger.DebugFormat("[{0}] received trigger instruction with id [{1}]", this.name, messageId);
            TriggerInstruction triggerInsruction = 
                SerializationFactory.DeserializeFromXml<TriggerInstruction>(message);
            this.ProcessTrigger(messageId, triggerInsruction);
        }
    }
}
